#include "board.h"
#include <cell.h>
#include <QPalette>
#include <QPixmap>
#include <QDebug>
#include <Qt>
#include <QMouseEvent>
#include <QPainter>
#include <QPen>
#include <pawn.h>
#include <piece.h>
#include <QMetaMethod>
#include <queen.h>
#include <fenrecognizer.h>
#include <QList>

Board::Board(QWidget *parent) : QWidget(parent)
{
    m_layout = new QHBoxLayout(this);
    setLayout(m_layout);
    for (int y = 0; y < 8; y++){
        for (int x = 0; x < 8; x++){
            m_cells[y*8 + x] = new Cell(y+1, x+1, m_layout);
        }
    }
    loadBoardImage();
    this->setFixedSize(64*8, 64*8);
    m_selection = new Selection;
    this->connect(m_selection, SIGNAL(move(Cell*, Cell*)), this, SLOT(move(Cell*, Cell*)));

    FENRecognizer fenrec;
    fenrec.recognize("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w", this);
}

Cell *Board::getCell(int x, int y)
{
    return m_cells[(x-1)*8 + y-1];
}

void Board::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton){
        m_selection->select(getCell(e->pos().x()/64 + 1, 8 - e->pos().y()/64));
        //Если клетка пуста, то не выделяем ее.         //Если в клетка фигура того же цвета, что и ходящего, то выделяем. В ином случае - нет.
        if (!m_editing){
            if (!(m_selection->getCell()->hasPiece() && (m_white_move == (m_selection->getCell()->getPiece()->getColor() == "W"))))
                m_selection->unselect();
        }else{
            if (!(m_selection->getCell()->hasPiece()))
                m_selection->unselect();
        }
        repaint();
    }
    e->accept();
}

void Board::paintEvent(QPaintEvent *event)
{
    if (m_selection->isSelected()){
       draw_selection(m_selection->getCell());
       if (m_selection->getCell()->hasPiece()){
           foreach (Cell* cell, m_selection->getCell()->getPiece()->getTips(this)) {
               if (cell != nullptr)
                   draw_selection(cell);
           }
       }
    }
}

QHBoxLayout *Board::getLayout() const
{
    return m_layout;
}

void Board::loadBoardImage()
{
    QPalette palette;
    QPixmap image(":/pieces/chessboard.png");
    palette.setBrush(QPalette::Background, image);
    this->setAutoFillBackground(true);
    this->setPalette(palette);
}

void Board::draw_selection(Cell *point)
{
    QPainter painter(this);
    painter.setPen(QPen(Qt::black, 4));
    painter.drawRect((point->getX()-1)*64, (8 - point->getY()) * 64, 64, 64);
}

void Board::clear()
{
    //Буду удалять тут Layout. Ой все плохо. Надо рефакторить код, чтобы не вылетало
    // THIS IS THE SOLUTION!
    // Delete all existing widgets, if any.
    if ( m_layout != nullptr )
    {
        QLayoutItem* item;
        while ((item = m_layout->takeAt(0)) != NULL)
        {
            ((Piece *)item->widget())->getCell()->setPiece(nullptr);
            delete item->widget();
            delete item;
        }
    }
    m_selection->unselect();

}

void transfer(Cell *start, Cell *end){
    if (end->hasPiece()){
        delete end->getPiece();
    }
    end->setPiece(start->getPiece());
    start->getPiece()->toCell(end);
    end->getPiece()->setCell(end);
    start->setPiece(nullptr);
}

void Board::move(Cell *start, Cell *end)
{
    // Надо будет сделать нормальный метод хода. Но потом. В конце концов вся логика ходов в этом методе
    // Переменная, говорящая, что ход был успешно сделан
    bool move_was_done{false};
    if (start->hasPiece()){
        if (end->hasPiece()){
            if (start->getPiece()->isFriend(end->getPiece())){
                //Пока ничего не делаем получается. Хотя для ракировки можно будет здесь написать что-то. Хотя нет
                if (m_editing){
                    delete end->getPiece();
                    end->setPiece(start->getPiece());
                    start->getPiece()->toCell(end);
                    end->getPiece()->setCell(end);
                    start->setPiece(nullptr);
                    move_was_done = true;
                }
            }else{
                //Бей вражину
                if (m_editing){
                    transfer(start, end);
//                    move_was_done = true;
                }else{
                    foreach(Cell* tip, start->getPiece()->getTips(this)){
                        if (tip == end){
                            transfer(start, end);
                            move_was_done = true;
                        }
                    }
                }
            }
        }else{
            if (m_editing){
                transfer(start, end);
//                move_was_done = true;
            }else{
                foreach(Cell* tip, start->getPiece()->getTips(this)){
                    if (tip == end){
                        transfer(start, end);
                        move_was_done = true;
                    }
                }
            }
        }
    }
    // Если убрать эту строку, то выделение после хода не будет сниматься и можно будет ходить непрерывно
    m_selection->unselect();

    if (move_was_done){
        m_white_move = !m_white_move;
    }
}

void Board::clearBoard()
{
    clear();
}

void Board::setEditing(bool state)
{
    m_editing = state;
}
